header {
	package org.asdt.core.internal.antlr;
}

/**
 *	@author Martin Schnabel
 */
class JavaDocParser extends Parser;

options {
	k = 3;
	exportVocab = JavaDoc;
	buildAST = true;
	defaultErrorHandler=true;
}

tokens {
	JAVADOC;
}

comment
	:	JAVADOC_START!
		commentBody
		JAVADOC_END!
	;

commentBody
	: 	(
		commentDescription
		)*
		(commentTag)* 
 	;

commentDescription
	:	COMMENT_TEXT
	;

inlineTag
	:	INLINE_TAG_START!
		IDENT
		COMMENT_TEXT
		INLINE_TAG_END!
	;

commentTag
	:	paramTag
	|	throwsTag
	|	returnTag
	|	seeTag
	|	authorTag
	|	deprecatedTag
	|	sinceTag
	|	versionTag
	;

paramTag
	:	"@param"^
		(COMMENT_TEXT)*
	;

throwsTag
	:	("@throws"^
	|	"@exception"
		)
		identifier
		(COMMENT_TEXT)*
	;

returnTag
	:	"@return"^
		(COMMENT_TEXT)*
	;

seeTag
	:	"@see"^
	(	seeCode
	|	seeString
	)
	;

seeCode
	:	(identifier (seeMethod)?)
	|	seeMethod
	;

seeMethod
	:	POUND IDENT
		(
		"("!
		((identifier COMMA!)* identifier)?
		")"!
		)?
	;

seeString
	:	STRING_LITERAL
	;

authorTag
	:	"@author"^
		(COMMENT_TEXT)*
	;

deprecatedTag
	:	"@deprecated"^
		(COMMENT_TEXT)*
	;

versionTag
	:	"@version"^
		(COMMENT_TEXT)*
	;

sinceTag
	:	"@since"^
		(COMMENT_TEXT)*
	;

identifier
	:	IDENT^
		(	options{greedy=true;}
		:	DOT! e1:IDENT^
		)* 
	;

class JavaDocLexer extends Lexer;

options {
	exportVocab=JavaDoc;    // call the vocabulary "JavaDoc"
	testLiterals=true;    	// don't automatically test for literals
	k=4;                   	// four characters of lookahead
	charVocabulary='\u0003'..'\u7FFE';
	codeGenBitsetTestThreshold=20;
	defaultErrorHandler=false;
}

POUND	:	'#' 	;
COMMA	:	','		;
DOT		:	'.'		;
//LPAREN	:	'('		;
//RPAREN	:	')'		;
LBRACE	:	'{'		;
RBRACE	:	'}'		;

IDENT options {testLiterals=true;}
	:	('a'..'z'|'A'..'Z'|'_'|'0'..'9'|'$')*
	;

// whitespace -- ignored
WS	:	(	' '
		|	'\t'
		|	'\f'
			// skip bom chars
		| 	'\u00EF' | '\u00BB'|'\u00BF' 
			// handle newlines
		|	NL
		)+
		{ _ttype = Token.SKIP; }
	;
protected NL	
	:	(	options {generateAmbigWarnings=false;}
		:	'\r' '\n'  	// DOS
		|	'\r'    	// Mac
		|	'\n'    	// Unix
		)
		{ newline(); _ttype = Token.SKIP;}
		;

STRING_LITERAL
	:	'"' 	
		(	options {generateAmbigWarnings=false;} 
		: 	ESC | ~('"'|'\n'|'\r'))* 
		'"'
	|	'\'' 	
		(	options {generateAmbigWarnings=false;}
		:	ESC | ~('\''|'\n'|'\r'))*
		'\''
	;

protected HEX_DIGIT
	:	('0'..'9'|'A'..'F'|'a'..'f')
	;
	
protected ESC
	:	'\\'
		(	'\\'|'n'|'r'|'t'|'b'|'f'|'"'|'\''
		|	('u')+ HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
		|	'0'..'3'
			( options{warnWhenFollowAmbig = false;}
			:	'0'..'7'( options{warnWhenFollowAmbig = false;}:'0'..'7')?
			)?
		|	'4'..'7'
			( options{warnWhenFollowAmbig = false;}
			:	'0'..'7'
			)?
		)
	;

JAVADOC_START
	:	"/**"
	;

JAVADOC_LINE
	:	'*'
	{ newline(); _ttype = Token.SKIP;}
	;

JAVADOC_END
	:	"*/"
	;

COMMENT_TEXT
	:	(~('\n'|'\r'|'@'))* ('\n'|'\r'('\n')?)
	;

INLINE_TAG_START
	:	"{@"
	;

INLINE_TAG_END
	:	'}'
	;